﻿using Autofac;
using Ewell.BizComponent.Service.IServer;
using Ewell.BizComponent.Service.Model.Constant;
using Ewell.BizComponent.Service.Model.Dto;
using Ewell.BizComponent.Service.Model.Insur.Request;
using Ewell.BizComponent.Service.Model.Insur.Response;
using Ewell.BizComponent.Service.Model.InterProxy;
using Ewell.BizComponent.Service.Model.Request;
using Ewell.BizComponent.UI.Core.Model;
using Ewell.BizComponent.UI.Core.VievModel;
using Ewell.BizComponent.UI.SearchItemCom.ViewModel;
using Ewell.BizComponent.UI.SearchPersonCom.ViewModel;
using Ewell.Interface.Common.Model.Common;
using Ewell.Interface.Common.Utils;
using MahApps.Metro.Controls.Dialogs;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

namespace Ewell.BizComponent.UI.Charge.ViewModel
{
    /// <summary>
    /// 预算主类
    /// </summary>
    public class PreSettlementVm : ViewModelBase
    {
        public IDialogCoordinator dialogCoordinator { get; set; } = DialogCoordinator.Instance;
        /// <summary>
        /// 预算请求
        /// </summary>
        public OutPreSettlementRequest outPreSettlementRequest { get; set; }
        /// <summary>
        /// 预算结果
        /// </summary>
        public PreSettlementResponse outPreSettlementResponse { get; set; }
        /// <summary>
        /// 患者
        /// </summary>
        private PatientVm _patient;
        public PatientVm patient
        {
            get => this._patient;
            set
            {
                if (this._patient != value)
                {
                    this._patient = value;
                    this.OnPropertyChanged(nameof(patient));
                }
            }
        }
        /// <summary>
        /// 已选择的医保费别
        /// </summary>
        private PatientTypeVm _selectedPatientType;
        public PatientTypeVm selectedPatientType
        {
            get
            {
                return _selectedPatientType;
            }
            set
            {
                if (_selectedPatientType != value)
                {
                    _selectedPatientType = value;
                    OnPropertyChanged(nameof(selectedPatientType));
                }
            }
        }
        /// <summary>
        /// 医保预算结果
        /// </summary>
        public OutPayResponse preOutPayResponse { get; set; }
        /// <summary>
        /// 选择患者费别显示
        /// </summary>
        private Visibility _choosePatientTypeViewVisib=Visibility.Collapsed;
        public Visibility choosePatientTypeViewVisib
        {
            get => _choosePatientTypeViewVisib;
            set
            {
                if (value != _choosePatientTypeViewVisib)
                {
                    _choosePatientTypeViewVisib = value;
                    OnPropertyChanged(nameof(choosePatientTypeViewVisib));
                }
            }
        }
        /// <summary>
        /// 检索组件主类
        /// </summary>
        private SearchPersonComVm _searchPersonComVm;
        public SearchPersonComVm searchPersonComVm
        {
            get => _searchPersonComVm;
            set
            {
                if (value != _searchPersonComVm)
                {
                    _searchPersonComVm = value;
                    OnPropertyChanged(nameof(searchPersonComVm));
                }
            }
        }
        /// <summary>
        /// 检索组件显示
        /// </summary>
        private Visibility _searchPersonViewVisib = Visibility.Collapsed;
        public Visibility searchPersonViewVisib
        {
            get => _searchPersonViewVisib;
            set
            {
                if (value != _searchPersonViewVisib)
                {
                    _searchPersonViewVisib = value;
                    OnPropertyChanged(nameof(searchPersonViewVisib));
                }
            }
        }
        /// <summary>
        /// 选择项主类
        /// </summary>
        private SearchItemComVm _searchItemComVm;
        public SearchItemComVm searchItemComVm
        {
            get => _searchItemComVm;
            set
            {
                if (_searchItemComVm != value)
                {
                    _searchItemComVm = value;
                    OnPropertyChanged(nameof(searchItemComVm));
                }
            }
        }
        /// <summary>
        /// 选择项组件显示
        /// </summary>
        private Visibility _searchItemViewVisib = Visibility.Collapsed;
        public Visibility searchItemViewVisib
        {
            get => _searchItemViewVisib;
            set
            {
                if (value != _searchItemViewVisib)
                {
                    _searchItemViewVisib = value;
                    OnPropertyChanged(nameof(searchItemViewVisib));
                }
            }
        }
        /// <summary>
        /// 继续按钮是否可用
        /// </summary>
        private bool _settBtnCanUsed = true;
        public bool settBtnCanUsed
        {
            get => _settBtnCanUsed;
            set
            {
                if (_settBtnCanUsed != value)
                {
                    _settBtnCanUsed = value;
                    OnPropertyChanged(nameof(settBtnCanUsed));
                }
            }
        }

        public IInsurServer insurServer { get; set; } = Global.Container.Resolve<IInsurServer>();

        public IOutSettlementServer outSettlementServer { get; set; } = Global.Container.Resolve<IOutSettlementServer>();

        public bool InsurFlag => selectedPatientType.no != "1";

        public PreSettlementVm()
        {
            this.searchPersonComVm = new SearchPersonComVm();
            this.searchItemComVm=new SearchItemComVm();
        }


        /// <summary>
        /// 预算
        /// </summary>
        public ICommand PreSettlement => new RelayCommand(async (object param) =>
        {
            //choosePatientTypeViewVisib = Visibility.Collapsed;
            //searchPersonViewVisib = Visibility.Collapsed;
            //searchItemViewVisib = Visibility.Collapsed;
            //HIS预算
            if (selectedPatientType == null || string.IsNullOrWhiteSpace(selectedPatientType.no))
            {
                choosePatientTypeViewVisib = Visibility.Visible;
                return;
            }
            if (outPreSettlementResponse == null)
            {
                #region HIS预算
                await PreSetAsync();
                #endregion
            }
            if (InsurFlag&& preOutPayResponse==null)//医保
            {
                #region 医保读卡显示
                if(!await InsurReadCardAsync()) return;
                #endregion

                #region 选择项显示
                if(!InsurSearchItem()) return;
                #endregion

                #region 医保预算
                if(!await InsurPreSetlAsync()) return;
                if(preOutPayResponse == null)
                    return;
                #endregion
            }
        });

        /// <summary>
        /// 取消预算
        /// </summary>
        public ICommand CancelPreSettlement => new RelayCommand(async (object param) =>
        {
            await CancelInsurPreSetlAsync();
        });

        /// <summary>
        /// HIS预算
        /// </summary>
        /// <returns></returns>
        private async Task PreSetAsync()
        {
            try
            {
                outPreSettlementRequest.preSettlementList.ForEach(item =>item.insurTypeId=selectedPatientType.no);
                LogHelper.Debug($"预算开始:{JsonConvert.SerializeObject(outPreSettlementRequest)}");
                LogHelper.Debug($"预算费别:{selectedPatientType.no}");
                outPreSettlementResponse = outSettlementServer.PreSettlement(outPreSettlementRequest);
            }
            catch (SpeedException ex)
            {
                Application.Current.Dispatcher.BeginInvoke(new Action(async () =>
                {
                    await this.dialogCoordinator.ShowMessageAsync(this, "警告", $"预算失败!{ex.Message}");
                }),DispatcherPriority.ContextIdle);
                return;
            }
            catch (Exception ex)
            {
                Application.Current.Dispatcher.BeginInvoke(new Action(async () =>
                {
                    await this.dialogCoordinator.ShowMessageAsync(this, "警告", $"预算失败!{ex.Message}");
                }), DispatcherPriority.ContextIdle);
                return;
            }
        }
        /// <summary>
        /// 医保读卡
        /// </summary>
        private async Task<bool> InsurReadCardAsync()
        {
            if (searchPersonViewVisib == Visibility.Visible&& searchPersonComVm.readCardResponse == null)
            {
                NeedReadCardResponse needReadCardResponse = insurServer.GetNeedReadCard(new RequestHeader() { interfaceId = long.Parse(selectedPatientType.interfaceId) }, new NeedReadCardRequest()
                {
                    currentBizTransactionCoding = outPreSettlementRequest.settlementTypeCode == "1" ? InsurBusinessCoding.HIS挂号预算.code : InsurBusinessCoding.HIS收费预算.code,
                    patientId = patient.patientId,
                    payMtNo = outPreSettlementResponse.settlementId.ToString(),
                    visitNo = outPreSettlementRequest.encounter.encounterId.ToString(),
                });
                //需要读卡
                if (needReadCardResponse.needReadCardStatus is "1" or "2")
                {
                    searchPersonViewVisib = Visibility.Visible;
                    if (needReadCardResponse.needReadCardStatus == "1")
                    {
                        await this.dialogCoordinator.ShowMessageAsync(this, "警告", $"接口设置必须读卡！请读卡后继续！");
                        return false;
                    }
                    return true;
                }
            }
            if (searchPersonComVm.readCardResponse == null&& searchPersonViewVisib != Visibility.Visible)
            {
                if (string.IsNullOrWhiteSpace(selectedPatientType.interfaceId) || selectedPatientType.interfaceId.Trim() == "0")
                {
                    await this.dialogCoordinator.ShowMessageAsync(this, "警告", $"结算的医保类型信息有误！请联系管理员排查绑定的接口信息!");
                    return false;
                }
                NeedReadCardResponse needReadCardResponse = insurServer.GetNeedReadCard(new RequestHeader() { interfaceId = long.Parse(selectedPatientType.interfaceId) }, new NeedReadCardRequest()
                {
                    currentBizTransactionCoding = outPreSettlementRequest.settlementTypeCode == "1" ? InsurBusinessCoding.HIS挂号预算.code : InsurBusinessCoding.HIS收费预算.code,
                    patientId = patient.patientId,
                    payMtNo = outPreSettlementResponse.settlementId.ToString(),
                    visitNo = outPreSettlementRequest.encounter.encounterId.ToString(),
                });
                //需要读卡
                if (needReadCardResponse.needReadCardStatus is "1" or "2")
                {
                    searchPersonViewVisib = Visibility.Visible;
                    if (needReadCardResponse.needReadCardStatus == "1")
                        settBtnCanUsed = false;
                    return false;
                }
                return true;
            }
            return true;
        }
        /// <summary>
        /// 医保选择项
        /// </summary>
        private bool InsurSearchItem()
        {
            if (searchItemViewVisib != Visibility.Visible)
            {
                this.searchItemComVm.outPreSettlementRequest = this.outPreSettlementRequest;
                this.searchItemComVm.readCardResponse=this.searchPersonComVm.readCardResponse;
                this.searchItemComVm.selectedPatientType = this.selectedPatientType;
                this.searchItemComVm.currentBizParams = this.outPreSettlementRequest.settlementTypeCode == "1" ? JsonConvert.SerializeObject(new OutRegisterBeforeRequest()
                {
                    outPayMtNo = this.outPreSettlementResponse.settlementId.ToString(),
                    patientId = this.patient.patientId,
                    visitNo = outPreSettlementRequest.encounter.encounterId.ToString(),
                }) : JsonConvert.SerializeObject(new OutPayPreviewRequest()
                {
                    outPayMtNo = this.outPreSettlementResponse.settlementId.ToString(),
                    patientId = this.patient.patientId,
                    visitNo = outPreSettlementRequest.encounter.encounterId.ToString(),
                });
                List<DataSelectItemResponse> dataSelectItemResponses = insurServer.InitDataSelectItem(new RequestHeader()
                {
                    cardInfo = searchPersonComVm.readCardResponse,
                    interfaceId = long.Parse(selectedPatientType.interfaceId),
                }, new DataSelectItemInitRequest()
                {
                    currentBizParams = this.searchItemComVm.currentBizParams,
                    currentBizTransactionCoding = this.outPreSettlementRequest.settlementTypeCode == "1" ? InsurBusinessCoding.HIS挂号预算.code : InsurBusinessCoding.HIS收费预算.code,
                });
                
                if (dataSelectItemResponses != null && dataSelectItemResponses.Count > 0)
                {
                    var datalist = new List<DataSelectItemVm>();
                    foreach (var item in dataSelectItemResponses)
                    {
                        var dataSelectItemVm=item.CopyProperties<DataSelectItemVm>();
                        if(item.componentTypeCoding == "1"&& !string.IsNullOrWhiteSpace(item.basicDataNo))
                        {
                            dataSelectItemVm.basicDataList = new List<BasicDataVm>();
                            var basicDatas = insurServer.SearchDataSelectItem(new RequestHeader() { interfaceId = long.Parse(searchItemComVm.selectedPatientType.interfaceId), cardInfo = this.searchItemComVm.readCardResponse, alreadySelectDataList = new List<DataSelectRequest>() }, new DataSelectItemQueryRequest() { basicDataDictTypeId = long.Parse(item.basicDataDictTypeId), basicDataDictTypeNo = item.basicDataDictTypeNo, currentBizParams = this.searchItemComVm.currentBizParams, currentBizTransactionCoding = this.searchItemComVm.outPreSettlementRequest.settlementTypeCode == "1" ? "101" : "201", keyword = string.Empty });
                            if (dataSelectItemVm != null)
                            {
                                dataSelectItemVm.basicDataList = new List<BasicDataVm>();
                                if (basicDatas != null && basicDatas.Count() > 0)
                                {
                                    foreach (var basicData in basicDatas)
                                    {
                                        dataSelectItemVm.basicDataList.Add(new BasicDataVm()
                                        {
                                            basicDataDictTypeId = dataSelectItemVm.basicDataDictTypeId,
                                            basicDataDictTypeNo = dataSelectItemVm.basicDataDictTypeNo,
                                            basicDataId = basicData.basicDataId,
                                            basicDataNo = basicData.basicDataNo,
                                            basicDataName = basicData.basicDataName,
                                            basicDataExtInfo = basicData.basicDataExtInfo,
                                            pinyin = basicData.pinyin,
                                            wubi = basicData.wubi,
                                        });
                                    }
                                }
                            }
                            dataSelectItemVm.selectedBasicData = dataSelectItemVm.basicDataList.FirstOrDefault(f=>f.basicDataNo== item.basicDataNo);
                        }
                        if (item.componentTypeCoding == "2" && !string.IsNullOrWhiteSpace(item.basicDataNo))
                        {
                            dataSelectItemVm.textBasicData = item.basicDataId;
                        }
                        if (item.componentTypeCoding == "3" && !string.IsNullOrWhiteSpace(item.basicDataId))
                        {
                            try
                            {
                                dataSelectItemVm.timeBasicData = DateTime.Parse(item.basicDataId);
                            }
                            catch (Exception)
                            {
                            }
                        }
                        if (item.componentTypeCoding == "4" && !string.IsNullOrWhiteSpace(item.basicDataId))
                        {
                            try
                            {
                                dataSelectItemVm.timeBasicData = DateTime.Parse(item.basicDataId);
                            }
                            catch (Exception)
                            {
                            }
                        }
                        //dataSelect.componentTypeCoding == "1"
                        datalist.Add(dataSelectItemVm);
                    }
                    this.searchItemComVm.dataSelectItemList = datalist;
                    searchItemViewVisib = Visibility.Visible;
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 医保预算
        /// </summary>
        private async Task<bool> InsurPreSetlAsync()
        {
            if (this.preOutPayResponse == null)
            {
                List<DataSelectRequest> alreadySelectDataList = new List<DataSelectRequest>();
                if (searchItemComVm.dataSelectItemList != null && searchItemComVm.dataSelectItemList.Count > 0)
                {
                    foreach (var dataSelect in this.searchItemComVm.dataSelectItemList)
                    {
                        if (dataSelect.componentTypeCoding == "1")
                        {
                            if (dataSelect.selectedBasicData == null) continue;
                            alreadySelectDataList.Add(dataSelect.selectedBasicData.CopyProperties<DataSelectRequest>());
                        }
                        else if (dataSelect.componentTypeCoding == "2")
                        {
                            if (!string.IsNullOrWhiteSpace(dataSelect.textBasicData)) continue;
                            alreadySelectDataList.Add(new DataSelectRequest()
                            {
                                basicDataDictTypeId = dataSelect.basicDataDictTypeId,
                                basicDataDictTypeNo = dataSelect.basicDataDictTypeNo,
                                basicDataId = dataSelect.textBasicData,
                                basicDataName = dataSelect.textBasicData,
                                basicDataNo = dataSelect.textBasicData,
                                basicDataExtInfo = dataSelect.textBasicData,
                            });
                        }
                        else if (dataSelect.componentTypeCoding == "3")
                        {
                            alreadySelectDataList.Add(new DataSelectRequest()
                            {
                                basicDataDictTypeId = dataSelect.basicDataDictTypeId,
                                basicDataDictTypeNo = dataSelect.basicDataDictTypeNo,
                                basicDataId = dataSelect.timeBasicData?.ToString("yyyy-MM-dd"),
                                basicDataName = dataSelect.timeBasicData?.ToString("yyyy-MM-dd"),
                                basicDataNo = dataSelect.timeBasicData?.ToString("yyyy-MM-dd"),
                                basicDataExtInfo = dataSelect.timeBasicData?.ToString("yyyy-MM-dd"),
                            });
                        }
                        else if (dataSelect.componentTypeCoding == "4")
                        {
                            alreadySelectDataList.Add(new DataSelectRequest()
                            {
                                basicDataDictTypeId = dataSelect.basicDataDictTypeId,
                                basicDataDictTypeNo = dataSelect.basicDataDictTypeNo,
                                basicDataId = dataSelect.timeBasicData?.ToString("yyyy-MM-dd HH:mm:ss"),
                                basicDataName = dataSelect.timeBasicData?.ToString("yyyy-MM-dd HH:mm:ss"),
                                basicDataNo = dataSelect.timeBasicData?.ToString("yyyy-MM-dd HH:mm:ss"),
                                basicDataExtInfo = dataSelect.timeBasicData?.ToString("yyyy-MM-dd HH:mm:ss"),
                            });
                        }
                    }
                }
                RequestHeader requestHeader = new RequestHeader()
                {
                    interfaceId = long.Parse(selectedPatientType.interfaceId),
                    alreadySelectDataList = alreadySelectDataList,
                    cardInfo = searchPersonComVm.readCardResponse,
                };
                try
                {
                    if (this.outPreSettlementRequest.settlementTypeCode == "1")
                    {
                        OutRegisterResponse outRegisterResponse = insurServer.previewOutRegister(requestHeader, new OutRegisterPreviewRequest()
                        {
                            outPayMtNo = this.outPreSettlementResponse.settlementId.ToString(),
                            patientId = this.patient.patientId,
                            visitNo = this.outPreSettlementRequest.encounter.encounterId.ToString(),
                        });
                        this.preOutPayResponse = outRegisterResponse.CopyProperties<OutPayResponse>();
                    }
                    else if (this.outPreSettlementRequest.settlementTypeCode == "2")
                    {
                        this.preOutPayResponse = insurServer.previewOutPay(requestHeader, new OutPayPreviewRequest()
                        {
                            outPayMtNo = this.outPreSettlementResponse.settlementId.ToString(),
                            patientId = this.patient.patientId,
                            visitNo = this.outPreSettlementRequest.encounter.encounterId.ToString(),
                        });
                    }
                }
                catch (SpeedException ex)
                {
                    await this.dialogCoordinator.ShowMessageAsync(this, "警告", $"医保预算失败!{ex.Message}");
                    return false;
                }
                catch (Exception ex)
                {
                    await this.dialogCoordinator.ShowMessageAsync(this, "警告", $"医保预算失败!{ex.Message}");
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 取消医保预算
        /// </summary>
        private async Task CancelInsurPreSetlAsync()
        {
            if (this.preOutPayResponse != null)
            {
                List<DataSelectRequest> alreadySelectDataList = new List<DataSelectRequest>();
                if (searchItemComVm.dataSelectItemList != null && searchItemComVm.dataSelectItemList.Count > 0)
                {
                    foreach (var dataSelect in this.searchItemComVm.dataSelectItemList)
                    {
                        if (dataSelect.componentTypeCoding == "1")
                        {
                            if (dataSelect.selectedBasicData == null) continue;
                            alreadySelectDataList.Add(dataSelect.selectedBasicData.CopyProperties<DataSelectRequest>());
                        }
                        else if (dataSelect.componentTypeCoding == "2")
                        {
                            alreadySelectDataList.Add(new DataSelectRequest()
                            {
                                basicDataDictTypeId = dataSelect.basicDataDictTypeId,
                                basicDataDictTypeNo = dataSelect.basicDataDictTypeNo,
                                basicDataId = dataSelect.textBasicData,
                                basicDataName = dataSelect.textBasicData,
                                basicDataNo = dataSelect.textBasicData,
                                basicDataExtInfo = dataSelect.textBasicData,
                            });
                        }
                        else if (dataSelect.componentTypeCoding == "3")
                        {
                            alreadySelectDataList.Add(new DataSelectRequest()
                            {
                                basicDataDictTypeId = dataSelect.basicDataDictTypeId,
                                basicDataDictTypeNo = dataSelect.basicDataDictTypeNo,
                                basicDataId = dataSelect.timeBasicData?.ToString("yyyy-MM-dd"),
                                basicDataName = dataSelect.timeBasicData?.ToString("yyyy-MM-dd"),
                                basicDataNo = dataSelect.timeBasicData?.ToString("yyyy-MM-dd"),
                                basicDataExtInfo = dataSelect.timeBasicData?.ToString("yyyy-MM-dd"),
                            });
                        }
                        else if (dataSelect.componentTypeCoding == "4")
                        {
                            alreadySelectDataList.Add(new DataSelectRequest()
                            {
                                basicDataDictTypeId = dataSelect.basicDataDictTypeId,
                                basicDataDictTypeNo = dataSelect.basicDataDictTypeNo,
                                basicDataId = dataSelect.timeBasicData?.ToString("yyyy-MM-dd HH:mm:ss"),
                                basicDataName = dataSelect.timeBasicData?.ToString("yyyy-MM-dd HH:mm:ss"),
                                basicDataNo = dataSelect.timeBasicData?.ToString("yyyy-MM-dd HH:mm:ss"),
                                basicDataExtInfo = dataSelect.timeBasicData?.ToString("yyyy-MM-dd HH:mm:ss"),
                            });
                        }
                    }
                }
                RequestHeader requestHeader = new RequestHeader()
                {
                    interfaceId = long.Parse(selectedPatientType.interfaceId),
                    alreadySelectDataList = alreadySelectDataList,
                    cardInfo = searchPersonComVm.readCardResponse,
                };
                try
                {
                    if (this.outPreSettlementRequest.settlementTypeCode == "1")
                    {
                        insurServer.cancelOutRegisterPreview(requestHeader, new OutRegisterCancelPreviewRequest() { outPayMtNo = this.outPreSettlementResponse.settlementId.ToString(), patientId = this.patient.patientId, visitNo = this.outPreSettlementRequest.encounter.encounterId.ToString() });
                    }
                    else if (this.outPreSettlementRequest.settlementTypeCode == "2")
                    {
                        insurServer.cancelOutPayPreview(requestHeader, new OutPayCancelPreviewRequest() { outPayMtNo = this.outPreSettlementResponse.settlementId.ToString(), patientId = this.patient.patientId, visitNo = this.outPreSettlementRequest.encounter.encounterId.ToString() });
                    }
                    this.preOutPayResponse = null;
                }
                catch (SpeedException ex)
                {
                    await this.dialogCoordinator.ShowMessageAsync(this, "警告", $"取消医保预算失败!可能存在单边账!{ex.Message}");
                    this.preOutPayResponse = null;
                    return;
                }
                catch (Exception ex)
                {
                    await this.dialogCoordinator.ShowMessageAsync(this, "警告", $"取消医保预算失败!可能存在单边账!{ex.Message}");
                    this.preOutPayResponse = null;
                    return;
                }
            }
        }
    }
}
